<!--
 * @Author: licongwei
 * @Date: 2022-03-14 16:45:42
 * @Description: 数字滚动组件
-->
<template>
  <div
    class="number-scroll"
    :style="{ height: fontSize + 'px', lineHeight: fontSize + 'px' }"
  >
    <p
      v-for="(item, index) in numArr"
      :key="index"
      class="number-scroll-item"
      :style="{ width: fontSize / 2 + 5 + 'px', fontSize: fontSize + 'px' }"
    >
      <span
        :ref="setItemRef"
        :style="{ color: color, letterSpacing: fontSize + 'px' }"
      >
        0123456789
      </span>
    </p>
  </div>
</template>
<script lang="ts">
import {
  defineComponent,
  reactive,
  ref,
  toRefs,
  nextTick,
  onBeforeUpdate,
  watch
} from 'vue'
interface IState {
  maxLen: number
  numArr: string[]
}
export default defineComponent({
  name: 'numberScroll',
  props: {
    number: {
      type: Number,
      default: 0
    },
    color: {
      type: String,
      default: '#000000'
    },
    fontSize: {
      type: [String, Number],
      default: 12
    }
  },
  setup(props) {
    // 获取dom数组
    let itemRefs = ref<HTMLElement[]>([])
    const setItemRef = (el: HTMLElement) => {
      if (el) {
        itemRefs.value.push(el)
      }
    }
    onBeforeUpdate(() => {
      itemRefs.value = []
    })
    // onUpdated(() => {
    //   console.log(itemRefs.value)
    // })
    const state: IState = reactive({
      timer: null,
      maxLen: 10, //最大长度
      numArr: [] //数字补零后分割为数组
    })

    //  数字补零操作，返回数组
    const prefixZero = (num: number, length: number) => {
      return (Array(length).join('') + num).slice(-length).split('')
    }

    // 设置每一位数字的偏移
    const setNumberTransform = () => {
      for (let index = 0; index < itemRefs.value.length; index++) {
        const elem = itemRefs.value[index]
        // 小数
        if (state.numArr[index] === '.') {
          elem.innerText = '.'
        } else {
          elem.style.transform = `translate(-50%,-${
            Number(state.numArr[index]) * 10
          }%`
        }
      }
    }
    const init = (number: number) => {
      nextTick(() => {
        state.numArr = prefixZero(number, state.maxLen)
        setTimeout(() => {
          setNumberTransform()
        }, 0)
      })
    }
    init(props.number)
    watch(
      () => props.number,
      (val) => {
        init(val)
      }
    )
    return {
      ...toRefs(state),
      setItemRef
    }
  }
})
</script>
<style lang="less" scoped>
.number-scroll {
  display: flex;
  justify-content: center;
  line-height: 100%;
  height: 100%;
  p {
    line-height: 100%;
    width: 12px;
    height: 100%;
    text-align: center;
    display: inline-block;
    font-size: 20px;
    position: relative;
    writing-mode: vertical-lr;
    text-orientation: upright;
    overflow: hidden;
    &:last-child {
      margin-right: 0;
    }
    span {
      position: absolute;
      top: 0;
      left: 50%;
      transform: translate(-50%, 0);
      transition: transform 1s;
      letter-spacing: 10px;
      font-family: 'AliHYAiHei';
    }
  }
}
</style>
